package org.arch_learn.ioc_aop.utils;

import org.apache.tools.ant.types.resources.URLResource;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.*;
import java.util.stream.Collectors;

public class ScanUtils {
    private static Set<String> classNames = new HashSet<>();

    private static Set<String> configClassNames = new HashSet<>();

    public static void scanPackage(String rootPackage) throws IOException {
        String scanPackagePath = Thread.currentThread().getContextClassLoader()
                .getResource("").getPath() + rootPackage.replaceAll("\\.", "/");

        File file = new File(scanPackagePath);
        File[] files = file.listFiles();
        for (File f : files) {
            if (f.isDirectory()) {
                scanPackage(rootPackage + "." + f.getName());
            } else if (f.getName().endsWith(".class")) {
                String name = f.getName().replaceAll("\\.class", "");
                String className = rootPackage + "." + name;
                classNames.add(className);
            }
        }
    }

    public static void doScanPackage(String rootPackage) throws IOException {
        scanPackage(rootPackage);
        loadFactories();
    }

    public static Set<String> getClassNames() {
        return classNames;
    }

    //获取自动配置类
    public static void loadFactories() throws IOException {
        //自动配置工厂的注入
        Enumeration<URL> systemResources = URLClassLoader.getSystemResources("META-INF/flash.factories");
        System.out.println(systemResources);
        Properties properties = new Properties();
        Map<String, Set<String>> map = new HashMap<>();
        while (systemResources.hasMoreElements()) {
            URL url = systemResources.nextElement();
            URLResource resources = new URLResource(url);
            properties.load(resources.getInputStream());
            properties.entrySet()
                    .stream().forEach(entry -> {
                        String key = (String) entry.getKey();
                        String multiValue = (String) entry.getValue();
                        Set<String> valueList = Arrays.stream(multiValue.split(",")).collect(Collectors.toSet());
                        if (map.get(key) == null) {
                            map.put(key, valueList);
                        } else {
                            map.get(key).addAll(valueList);
                        }
                    });
        }
        Set<String> autoConfigurationsClasses = map.get("org.arch_learn.boot.autoconfigure.EnableAutoConfiguration");
        configClassNames.addAll(autoConfigurationsClasses);

    }

    public static Set<String> getConfigClassNames() throws IOException {
        return configClassNames;
    }
}
